//
//  BMapNavigationViewController.m
//  GolfFriend
//
//  Created by Vescky on 14-3-19.
//  Copyright (c) 2014年 vescky.org. All rights reserved.
//

#import "BMapNavigationViewController.h"
#import "CommonUtility.h"
#import "AppsBBubbleAnnotationView.h"
#import "AnimationUtility.h"
#import <QuartzCore/QuartzCore.h>
#import "RouteAnnotation2.h"
#import "AppDelegate.h"

@interface BMapNavigationViewController () {
    UIView *rightActivityView;
    UILabel *loadingLabel;
    UIActivityIndicatorView *rightActivityLoadingView;
    NSArray *currentViews;
    
    RouteAnnotation2 *endAnnotation;
    BMKAnnotationView *selectedAV;
    AppsBBubbleAnnotationView *bubbleAnnotationView;
    
    NSInteger regionChangeCount;
}

@end

@implementation BMapNavigationViewController

@synthesize startPointLocation;
@synthesize endPointLocation;
@synthesize stadiumInfo;
@synthesize startPointCoordinateLatitude,startPointCoordinateLongitude;
@synthesize endPointCoordinateLatitude,endPointCoordinateLongitude;

#pragma mark - UIView lifecycle

- (void)loadView {
    CGFloat height = iPhone5 ? 416.0f + 88.0f : 416.0f;
//	UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, height)];
//	self.view = contentView;
    
    routeMapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, height)];
    self.view = routeMapView;
    
    regionChangeCount = 0;
    
    rightActivityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 30)];
    [rightActivityView setBackgroundColor:[UIColor clearColor]];
    rightActivityLoadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    [rightActivityView setClipsToBounds:YES];
    [rightActivityLoadingView setFrame:CGRectMake(0, 5, 20, 20)];
    [rightActivityView addSubview:rightActivityLoadingView];
    [rightActivityLoadingView setHidesWhenStopped:YES];
    [rightActivityLoadingView startAnimating];
    loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(25, 0, 60, 30)];
    [loadingLabel setBackgroundColor:[UIColor clearColor]];
    [loadingLabel setTextColor:[UIColor whiteColor]];
    [loadingLabel setFont:[UIFont systemFontOfSize:14]];
    [loadingLabel setText:@"正在导航..."];
    [rightActivityView addSubview:loadingLabel];
    [rightActivityView setAlpha:0.0f];
    
    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightActivityView];
    self.navigationItem.rightBarButtonItem = rightItem;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [super customBackButton];
    self.title = @"路线导航";
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self initView];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(selectAnnotationViewAfterDelay) object:nil];
    if(routeMapView){
        routeMapView.delegate = nil;
        routeMapSearch.delegate = nil;
        routeMapView = nil;
        routeMapSearch = nil;
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)initView {
    isRetina2 = NO;
    
    BMKCoordinateRegion region;
    region.center.latitude     = [APP_DELEGATE userCurrentLocation].coordinate.latitude;
    region.center.longitude    = [APP_DELEGATE userCurrentLocation].coordinate.longitude;
    region.span.latitudeDelta  = 0.2;
    region.span.longitudeDelta = 0.2;
    [routeMapView setRegion:region];
    
    routeMapView.delegate = self;
    routeMapView.scrollEnabled = YES;
    routeMapView.zoomEnabled = YES;
    routeMapView.showsUserLocation = NO;
//    routeMapView.zoomLevel = 17;
    
    startPointCoordinateLatitude = [APP_DELEGATE userCurrentLocation].coordinate.latitude;
    startPointCoordinateLongitude = [APP_DELEGATE userCurrentLocation].coordinate.longitude;
    
    CLLocation *stadiumLocation = getGfLocation([stadiumInfo objectForKey:@"position"]);
    endPointCoordinateLatitude = stadiumLocation.coordinate.latitude;
    endPointCoordinateLongitude = stadiumLocation.coordinate.longitude;
    
    bubbleAnnotationView = [[AppsBBubbleAnnotationView alloc] initWithFrame:CGRectMake(0, 0, 160, 40)];
    bubbleAnnotationView.hidden = YES;
    
    isRetina2 = YES;
    
    routeMapSearch = [[BMKSearch alloc] init];
    routeMapSearch.delegate = self;
    
    [self doSearchRoute];
}


#pragma mark - Private

- (void)doSearchRoute {
    BMKPlanNode *start = [[BMKPlanNode alloc] init];
	start.pt = CLLocationCoordinate2DMake(startPointCoordinateLatitude, startPointCoordinateLongitude);
	start.name = @"我的位置";
	BMKPlanNode *end = [[BMKPlanNode alloc] init];
    end.pt = CLLocationCoordinate2DMake(endPointCoordinateLatitude, endPointCoordinateLongitude);
	end.name = [stadiumInfo objectForKey:@"name"];
    
	BOOL flag = [routeMapSearch drivingSearch:@"" startNode:start endCity:@"" endNode:end];
	if(!flag) {
        [self performSelector:@selector(hideLoading:) withObject:@"导航失败!" afterDelay:0.5f];
    }
}

- (void)hideLoading:(NSString *)text {
    [UIView animateWithDuration:0.3f animations:^(void){
        [rightActivityLoadingView setAlpha:1.0f];
        [loadingLabel setText:text];
        [rightActivityLoadingView stopAnimating];
    }];
}

- (void)selectAnnotationAfterDelay {
    [self performSelectorOnMainThread:@selector(selectAnnotation) withObject:nil waitUntilDone:YES];
}

- (void)selectAnnotation {
    if(endAnnotation){
        [routeMapView selectAnnotation:endAnnotation animated:NO];
    }
}

#pragma mark - BMKAnnotationViewDelegate
- (void)selectAnnotationViewAfterDelay {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(selectAnnotationViewAfterDelay) object:nil];
    if (selectedAV) {
        [self showBubble:YES];
        [self changeBubblePosition];
    }
}

- (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    
}

- (void)mapView:(BMKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    if (selectedAV) {
        [self showBubble:NO];
    }
}

- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    //    if (selectedAV) {
    //        [self showBubble:YES];
    //        [self changeBubblePosition];
    //    }
    regionChangeCount++;
    if(regionChangeCount >= 3){
        [self performSelector:@selector(selectAnnotationViewAfterDelay) withObject:nil afterDelay:0.25f];
    }
}

- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view {
    if ([view isKindOfClass:[BMKAnnotationView class]]) {
        selectedAV = view;
        
        RouteAnnotation2 *annotation = (RouteAnnotation2 *)view.annotation;
        if (bubbleAnnotationView.superview == nil) {
            [view.superview addSubview:bubbleAnnotationView];
            bubbleAnnotationView.layer.zPosition = 1;
        }
        if(annotation.type == 1){
            bubbleAnnotationView.dataInfo = stadiumInfo;
        }else if(annotation.type == 0){
            bubbleAnnotationView.dataInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"我的位置",@"address", nil];
        }else{
            bubbleAnnotationView.dataInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:annotation.title,@"address", nil];
        }
    }
    else {
        selectedAV = nil;
    }
    [mapView setCenterCoordinate:view.annotation.coordinate animated:YES];
}

- (BMKAnnotationView*)getRouteAnnotationView:(BMKMapView *)mapview viewForAnnotation:(RouteAnnotation2 *)routeAnnotation {
	BMKAnnotationView *view = nil;
	switch (routeAnnotation.type) {
		case 0:
		{
			view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"start_node"];
			if (view == nil) {
				view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"start_node"];
				view.image = [UIImage imageNamed:@"mapapi.bundle/images/icon_nav_start.png"];
				view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));
				view.canShowCallout = NO;
			}
			view.annotation = routeAnnotation;
            view.tag = 31;
		}
			break;
		case 1:
		{
			view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"end_node"];
			if (view == nil) {
				view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"end_node"];
				view.image = [UIImage imageNamed:@"mapapi.bundle/images/icon_nav_end.png"];
				view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));
				view.canShowCallout = NO;
			}
			view.annotation = routeAnnotation;
            view.tag = 32;
		}
			break;
		case 2:
		{
			view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"bus_node"];
			if (view == nil) {
				view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"bus_node"];
				view.image = [UIImage imageNamed:@"mapapi.bundle/images/icon_nav_bus.png"];
				view.canShowCallout = NO;
			}
			view.annotation = routeAnnotation;
            view.tag = 33;
		}
			break;
		case 3:
		{
			view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"rail_node"];
			if (view == nil) {
				view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"rail_node"];
				view.image = [UIImage imageNamed:@"mapapi.bundle/images/icon_nav_rail.png"];
				view.canShowCallout = NO;
			}
			view.annotation = routeAnnotation;
            view.tag = 34;
		}
			break;
		case 4:
		{
			view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"route_node"];
			if (view == nil) {
				view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"route_node"];
				view.canShowCallout = NO;
			} else {
				[view setNeedsDisplay];
			}
            view.tag = 35;
			
            //			UIImage* image = [UIImage imageNamed:@"mapapi.bundle/images/icon_direction.png"];
            //			view.image = [image imageRotatedByDegrees:routeAnnotation.degree];
			view.annotation = routeAnnotation;
			
		}
			break;
		default:
			break;
	}
	
	return view;
}

- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation {
	if ([annotation isKindOfClass:[RouteAnnotation2 class]]) {
		return [self getRouteAnnotationView:view viewForAnnotation:(RouteAnnotation2 *)annotation];
	}
	return nil;
}

- (BMKOverlayView*)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay {
	if ([overlay isKindOfClass:[BMKPolyline class]]) {
        BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
        polylineView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:1];
        polylineView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        polylineView.lineWidth = 3.0;
        return polylineView;
    }
	return nil;
}

- (void)onGetDrivingRouteResult:(BMKPlanResult *)result errorCode:(int)error {
    [UIView animateWithDuration:0.3f animations:^(void){
        [rightActivityView setAlpha:0.0f];
        [rightActivityLoadingView stopAnimating];
    }];
    //	NSLog(@"onGetDrivingRouteResult:error:%d", error);
	if (error == BMKErrorOk) {
		BMKRoutePlan* plan = (BMKRoutePlan*)[result.plans objectAtIndex:0];
		
		RouteAnnotation2* item = [[RouteAnnotation2 alloc] init];
		item.coordinate = result.startNode.pt;
		item.title = @"我的位置";
		item.type = 0;
		[routeMapView addAnnotation:item];
		
		int index = 0;
		int size = [plan.routes count];
		for (int i = 0; i < 1; i++) {
			BMKRoute* route = [plan.routes objectAtIndex:i];
			for (int j = 0; j < route.pointsCount; j++) {
				int len = [route getPointsNum:j];
				index += len;
			}
		}
		
		BMKMapPoint* points = new BMKMapPoint[index];
        
		index = 0;
		
		for (int i = 0; i < 1; i++) {
			BMKRoute* route = [plan.routes objectAtIndex:i];
			for (int j = 0; j < route.pointsCount; j++) {
				int len = [route getPointsNum:j];
				BMKMapPoint* pointArray = (BMKMapPoint*)[route getPoints:j];
				memcpy(points + index, pointArray, len * sizeof(BMKMapPoint));
				index += len;
			}
			size = route.steps.count;
			for (int j = 0; j < size; j++) {
				BMKStep* step = [route.steps objectAtIndex:j];
				item = [[RouteAnnotation2 alloc]init];
				item.coordinate = step.pt;
				item.title = step.content;
				item.degree = step.degree * 30;
				item.type = 4;
				[routeMapView addAnnotation:item];
                
			}
			
		}
		
		item = [[RouteAnnotation2 alloc] init];
		item.coordinate = result.endNode.pt;
		item.type = 1;
		item.title = [stadiumInfo objectForKey:@"name"];
        item.subtitle = [stadiumInfo objectForKey:@"address"];
		[routeMapView addAnnotation:item];
        
		BMKPolyline* polyLine = [BMKPolyline polylineWithPoints:points count:index];
		[routeMapView addOverlay:polyLine];
		delete []points;
        
        endAnnotation = item;
        
        [self selectRegion];
	}else{
        [self performSelector:@selector(hideLoading:) withObject:@"导航失败!" afterDelay:0.5f];
        
    }
}

- (void)onGetPoiResult:(NSArray *)poiResultList searchType:(int)type errorCode:(int)error {
    
}

- (void)onGetAddrResult:(BMKAddrInfo *)result errorCode:(int)error {
    
}

- (void)selectRegion {
    CLLocationDegrees maxLat = -90.0f;
    CLLocationDegrees maxLon = -180.0f;
    CLLocationDegrees minLat = 90.0f;
    CLLocationDegrees minLon = 180.0f;
    if(startPointCoordinateLatitude > maxLat) {
        maxLat = startPointCoordinateLatitude;
    }
    if(startPointCoordinateLatitude < minLat) {
        minLat = startPointCoordinateLatitude;
    }
    if(startPointCoordinateLongitude > maxLon) {
        maxLon = startPointCoordinateLongitude;
    }
    if(startPointCoordinateLongitude < minLon) {
        minLon = startPointCoordinateLongitude;
    }
    if(endPointCoordinateLatitude > maxLat) {
        maxLat = endPointCoordinateLatitude;
    }
    if(endPointCoordinateLatitude < minLat) {
        minLat = endPointCoordinateLatitude;
    }
    if(endPointCoordinateLongitude > maxLon) {
        maxLon = endPointCoordinateLongitude;
    }
    if(endPointCoordinateLongitude < minLon) {
        minLon = endPointCoordinateLongitude;
    }
    
    //    maxLat = endPointCoordinateLatitude;
    //    minLat = endPointCoordinateLatitude;
    
    BMKCoordinateRegion region;
    region.center.latitude     = (maxLat + minLat) / 2;
    region.center.longitude    = (maxLon + minLon) / 2;
    region.span.latitudeDelta  = (maxLat - minLat) * 2.0f;
    region.span.longitudeDelta = (maxLon - minLon) * 2.0f;
    
    if(routeMapView){
        [routeMapView setRegion:region animated:NO];
    }
    
    [self performSelector:@selector(selectAnnotationAfterDelay) withObject:nil afterDelay:0.5f];
}

#pragma mark - Show Bubble Animation

- (void)showBubble:(BOOL)show {
    if(show) {
        [bubbleAnnotationView showFromRect:selectedAV.frame];
        [AnimationUtility bubbleAnimation:bubbleAnnotationView show:YES];
    }else {
        [AnimationUtility bubbleAnimation:bubbleAnnotationView show:NO];
    }
}

- (void)changeBubblePosition {
    if (selectedAV) {
        CGRect rect = selectedAV.frame;
        CGPoint center;
        center.x = rect.origin.x + rect.size.width/2;
        center.y = rect.origin.y - bubbleAnnotationView.frame.size.height/2 + 8;
        bubbleAnnotationView.center = center;
    }
}


@end
